using System;
using System.ComponentModel;
using System.Xml.Serialization;

namespace com.exceptionalsoftware.spacetime.KML
{
	[Serializable()]
    [XmlType(TypeName = "FeatureType")]
    [XmlInclude(typeof(Container))]
    [XmlInclude(typeof(Document))]
    [XmlInclude(typeof(Folder))]
    [XmlInclude(typeof(Placemark))]
    [XmlInclude(typeof(NetworkLink))]
    [XmlInclude(typeof(Overlay))]
    [XmlInclude(typeof(GroundOverlay))]
    [XmlInclude(typeof(ScreenOverlay))]
    [XmlInclude(typeof(PhotoOverlay))]
    public abstract class Feature : ObjectType
	{
        private SimpleGenericList<StyleSelector> stylesField;
        private string nameField, descriptionField, styleUrlField;
        private string addressField, phoneNumberField, metadataField;
        private bool visibility, openField;
        private TimePrimitive timeField;
        private LookAtType lookAtField;
        //private LookAtType viewField;
        private Camera cameraField;
        private Snippet snippetField;
        private Region regionField;
        private ExtendedData extendedDataField;

        public Feature()
        {
            this.stylesField = new SimpleGenericList<StyleSelector>();
            this.visibility = true;
            this.openField = true;
        }

        [XmlElement(ElementName = "name", DataType = "string")]
        public string Name
        {
            get { return this.nameField; }
            set { this.nameField = value; }
        }

        [XmlElement(ElementName = "visibility", DataType = "boolean")]
        [DefaultValue(true)]
        public bool  Visible
        {
            get { return this.visibility; }
            set { this.visibility = value; }
        }

        [XmlElement(ElementName = "open", DataType = "boolean")]
        [DefaultValue(true)]
        public bool Open
        {
            get { return this.openField; }
            set { this.openField = value; }
        }

        [XmlElement(ElementName = "Snippet", Type = typeof(Snippet))]
        public Snippet Snippet
        {
            get { return this.snippetField; }
            set { this.snippetField = value; }
        }

        [XmlElement(ElementName = "description", DataType = "string")]
        public string Description
        {
            get { return this.descriptionField; }
            set { this.descriptionField = value; }
        }

        [XmlElement(ElementName = "address", DataType = "string")]
        public string Address
        {
            get { return this.addressField; }
            set { this.addressField = value; }
        }

        [XmlElement(ElementName = "phoneNumber", DataType = "string")]
        public string PhoneNumber
        {
            get { return this.phoneNumberField; }
            set { this.phoneNumberField = value; }
        }

        [XmlElement(ElementName = "styleUrl", DataType = "anyURI")]
        public string StyleUrl
        {
            get { return this.styleUrlField; }
            set { this.styleUrlField = value; }
        }

        [XmlElement(ElementName = "Style", Type = typeof(Style))]
        [XmlElement(ElementName = "StyleMap", Type = typeof(StyleMap))]
        public StyleSelector[] StylesArray
        {
            get { return this.stylesField.ToArray(); }
            set { this.stylesField = new SimpleGenericList<StyleSelector>(value); }
        }

        [XmlIgnore()]
        public SimpleGenericList<StyleSelector> Styles
        {
            get { return this.stylesField; }
        }

        [XmlElement(ElementName = "LookAt", Type = typeof(LookAtType))]
        public LookAtType LookAt
        {
            get { return this.lookAtField; }
            set { this.lookAtField = value; }
        }

        [XmlElement(ElementName = "View", Type = typeof(LookAtType))]
        public LookAtType View
        {
            get { return this.lookAtField; }
            set { this.lookAtField = value; }
        }

        [XmlElement(ElementName = "Camera", Type = typeof(Camera))]
        public Camera Camera
        {
            get { return this.cameraField; }
            set { this.cameraField = value; }
        }

        [XmlElement(ElementName = "TimeStamp", Type = typeof(TimeStamp))]
        [XmlElement(ElementName = "TimeSpan", Type = typeof(TimeSpan))]
        public TimePrimitive Time
        {
            get { return this.timeField; }
            set { this.timeField = value; }
        }

        [XmlElement(ElementName = "Region", Type = typeof(Region))]
        public Region Region
        {
            get { return this.regionField; }
            set { this.regionField = value; }
        }

        [XmlElement(ElementName = "Metadata", DataType = "string")]
        public string Metadata
        {
            get { return this.metadataField; }
            set { this.metadataField = value; }
        }

        [System.Xml.Serialization.XmlElementAttribute("ExtendedData", typeof(ExtendedData))]
        public ExtendedData ExtendedData
        {
            get { return this.extendedDataField; }
            set { this.extendedDataField = value; }
        }

    }
}